package org.dromara.system.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.dromara.common.core.utils.MapstructUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.dromara.system.domain.SysAgent;
import org.dromara.system.domain.bo.SysAgentBo;
import org.dromara.system.domain.query.SysAgentQuery;
import org.dromara.system.domain.vo.SysAgentVo;
import org.dromara.system.mapper.SysAgentMapper;
import org.dromara.system.service.ISysAgentService;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.List;

/**
 * 代理商Service业务层处理
 *
 * @author yixiacoco
 * @date 2025-09-03
 */
@Service
public class SysAgentServiceImpl extends ServiceImpl<SysAgentMapper, SysAgent> implements ISysAgentService {

//    @Autowired
//    private RedisTemplate<String, Long> redisTemplate;

    /**
     * 查询代理商
     *
     * @param agentId 主键
     * @return SysAgentVo
     */
    @Override
    public SysAgentVo queryById(String agentId) {
        return baseMapper.selectVoById(agentId);
    }

    /**
     * 分页查询代理商列表
     *
     * @param query 查询对象
     * @return 代理商分页列表
     */
    @Override
    public TableDataInfo<SysAgentVo> queryPageList(SysAgentQuery query) {
        TableDataInfo<SysAgentVo> page = PageQuery.of(() -> baseMapper.queryListWithParentName(query));
        return page;
    }

    /**
     * 查询代理商列表
     *
     * @param query 查询对象
     * @return 代理商列表
     */
    @Override
    public List<SysAgentVo> queryList(SysAgentQuery query) {
        return baseMapper.queryListWithParentName(query);
    }

    /**
     * 新增代理商
     *
     * @param bo 代理商新增业务对象
     * @return 是否新增成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(SysAgentBo bo) {
        // 校验代理商名称唯一性
        if (!checkAgentNameUnique(bo.getAgentName(), null)) {
            throw new RuntimeException("代理商名称已存在");
        }
        // 校验税号唯一性
        if (!checkTaxNumberUnique(bo.getTaxNumber(), null)) {
            throw new RuntimeException("税号已存在");
        }
        // 校验联系电话唯一性
        if (!checkContactInfoUnique(bo.getContactInfo(), null)) {
            throw new RuntimeException("联系电话已存在");
        }
        // 生成代理商编号
        bo.setAgentCode(generateAgentCode());

        SysAgent add = MapstructUtils.convert(bo, SysAgent.class);
        return save(add);
    }

    /**
     * 修改代理商
     *
     * @param bo 代理商编辑业务对象
     * @return 是否修改成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(SysAgentBo bo) {
        // 校验代理商名称唯一性
        if (!checkAgentNameUnique(bo.getAgentName(), bo.getAgentId())) {
            throw new RuntimeException("代理商名称已存在");
        }
        // 校验税号唯一性
        if (!checkTaxNumberUnique(bo.getTaxNumber(), bo.getAgentId())) {
            throw new RuntimeException("税号已存在");
        }
        // 校验联系电话唯一性
        if (!checkContactInfoUnique(bo.getContactInfo(), bo.getAgentId())) {
            throw new RuntimeException("联系电话已存在");
        }

        SysAgent update = MapstructUtils.convert(bo, SysAgent.class);
        return updateById(update);
    }

    /**
     * 批量删除代理商信息
     *
     * @param ids 待删除的主键集合
     * @return 是否删除成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<String> ids) {
        return removeByIds(ids);
    }

    @Override
    public List<SysAgentVo> queryEnabledAgents(String level) {
        LambdaQueryWrapper<SysAgent> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysAgent::getStatus, "1")
               .in(level != null, SysAgent::getLevel, List.of("1", "2"))
               .select(SysAgent::getAgentId, SysAgent::getAgentName, SysAgent::getLevel,SysAgent::getParentAgentId);
        return baseMapper.selectVoList(wrapper);
    }

    /**
     * 校验代理商名称是否唯一
     *
     * @param agentName 代理商名称
     * @param agentId   代理商ID(更新时传入)
     * @return 是否唯一
     */
    private boolean checkAgentNameUnique(String agentName, String agentId) {
        LambdaQueryWrapper<SysAgent> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysAgent::getAgentName, agentName)
               .eq(SysAgent::getStatus, "1") // 1表示启用状态
               .ne(agentId != null, SysAgent::getAgentId, agentId);
        return baseMapper.selectCount(wrapper) == 0;
    }

    /**
     * 校验税号是否唯一
     *
     * @param taxNumber 税号
     * @param agentId   代理商ID(更新时传入)
     * @return 是否唯一
     */
    private boolean checkTaxNumberUnique(String taxNumber, String agentId) {
        LambdaQueryWrapper<SysAgent> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysAgent::getTaxNumber, taxNumber)
               .eq(SysAgent::getStatus, "1") // 1表示启用状态
               .ne(agentId != null, SysAgent::getAgentId, agentId);
        return baseMapper.selectCount(wrapper) == 0;
    }

    /**
     * 校验联系电话是否唯一
     *
     * @param contactInfo 联系电话
     * @param agentId     代理商ID(更新时传入)
     * @return 是否唯一
     */
    private boolean checkContactInfoUnique(String contactInfo, String agentId) {
        LambdaQueryWrapper<SysAgent> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysAgent::getContactInfo, contactInfo)
               .eq(SysAgent::getStatus, "1") // 1表示启用状态
               .ne(agentId != null, SysAgent::getAgentId, agentId);
        return baseMapper.selectCount(wrapper) == 0;
    }



    /**
     * 生成代理商编号
     *
     * @return 生成的编号
     */
    private String generateAgentCode() {
        String datePart = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        long uniqueId = IdUtil.getSnowflakeNextId();
        return datePart + String.format("%05d", uniqueId % 100000);
    }


}
